#pragma once
#include "parser.h"
#include <vector>
#include <unordered_map>
#include <string>
#include <memory>
#include <iostream>
#include <stack>

using namespace std;

// 符号类型
enum class SymbolType {
    VARIABLE,
    FUNCTION,
    PARAMETER
};

// 符号表条目
struct Symbol {
    string name;
    SymbolType type;
    string dataType; // "int" 或 "void"
    vector<string> paramTypes; // 函数参数类型列表
};

class TypeSystem {
public:
    static bool isInteger(const string& type) {
        return type == "int";
    }

    static bool isCompatible(const string& t1, const string& t2) {
        // 简单类型兼容性检查
        return t1 == t2;
    }
};

// 作用域类
class Scope {
public:
    unordered_map<string, Symbol> symbols;

    bool declare(const string& name, const Symbol& symbol) {
        if (symbols.find(name) != symbols.end()) {
            return false; // 重复声明
        }
        symbols[name] = symbol;
        return true;
    }

    Symbol* lookup(const string& name) {
        auto it = symbols.find(name);
        if (it != symbols.end()) {
            return &it->second;
        }
        return nullptr;
    }
};

// 语义分析器类
class SemanticAnalyzer {
public:
    SemanticAnalyzer() {
        enterScope(); // 全局作用域
    }

    void analyze(unique_ptr<ASTNode>& root);

    // 错误处理
    void error(const string& message) {
        errors.push_back("Semantic error: " + message);
    }

    void printErrors() {
        for (const auto& err : errors) {
            cerr << err << endl;
        }
    }

    string getExprType(ExprNode* node) {
        if (auto literal = dynamic_cast<NumberNode*>(node)) {
            return literal->type;
        }
        if (auto ident = dynamic_cast<ExprNode*>(node)) {
            if (auto sym = lookupSymbol(ident->op)) {
                return sym->dataType; // 返回变量类型
            }
        }
        return "unknown";
    }

    // 节点分析方法
    void analyzeCompUnit(CompUnitNode* node);
    void analyzeFuncDef(FuncDefNode* node);
    void analyzeStmt(StmtNode* node, const string& currentReturnType);
    void analyzeExpr(ExprNode* node);
    void analyzeBlock(StmtNode* node, const string& currentReturnType);

    bool hasErrors() const { return !errors.empty(); }

private:
    vector<string> errors;
    vector<unique_ptr<Scope>> scopes;

    // 作用域管理
    void enterScope() {
        scopes.push_back(make_unique<Scope>());
    }

    void exitScope() {
        if (!scopes.empty()) {
            scopes.pop_back();
        }
    }

    Scope* currentScope() {
        if (scopes.empty()) return nullptr;
        return scopes.back().get();
    }

    bool declareSymbol(const string& name, SymbolType type, const string& dataType = "",
        const vector<string>& paramTypes = {}) {
        if (!currentScope()) return false;

        Symbol symbol{ name, type, dataType, paramTypes };
        if (!currentScope()->declare(name, symbol)) {
            error("Redeclaration of '" + name + "'");
            return false;
        }
        return true;
    }

    Symbol* lookupSymbol(const string& name) {
        // 从当前作用域向全局作用域查找
        for (auto it = scopes.rbegin(); it != scopes.rend(); ++it) {
            if (auto symbol = (*it)->lookup(name)) {
                return symbol;
            }
        }
        return nullptr;
    }


    // 类型检查辅助函数
    bool isBoolOp(const string& op);
    bool isArithmeticOp(const string& op);
    bool isComparisonOp(const string& op);
    bool isLogicalOp(const string& op);
};

// 访问者模式适配器
void analyzeNode(SemanticAnalyzer& analyzer, ASTNode* node, const string& currentReturnType = "");

